package com.xzj.admin.resource.analysis.handle.async;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xzj.admin.analysis.base.common.cache.SubResourceCache;
import com.xzj.admin.analysis.base.common.cache.VirtualConvertCache;
import com.xzj.admin.analysis.base.common.handle.CommonAbstractAnalysisHandle;
import com.xzj.admin.analysis.base.constants.CommonEnums;
import com.xzj.admin.analysis.base.domain.ResMessageManage;
import com.xzj.admin.analysis.base.domain.CommonFlowInfo;
import com.xzj.admin.analysis.base.util.AnalysisCommonUtil;
import com.xzj.admin.resource.analysis.cache.BaseCache;
import com.xzj.admin.resource.analysis.cache.GroovyScriptCache;
import com.xzj.admin.resource.analysis.domain.entity.ResMessageSource;
import groovy.lang.Script;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @program: xzj-admin
 * @ClassName: AsyncRowHandle
 * @description: 遍历循环每一行数据处理异步线程
 * @author: XiaZunJun
 * @create: 2024-11-19 17:20
 */
@Component
@Slf4j
public class AsyncRowHandle {

    @Resource
    private CommonAbstractAnalysisHandle abstractAnalysisHandle;

    /**
     * 循环遍历每一条数据
     *
     * @param info 解析流转对象，主要公用信息的保存
     * @param row  单条消息
     * @author xiazunjun
     * @date 2023/8/15 17:30
     */
    @Async("analysisTask")
    public void foreachRow(CommonFlowInfo info, JSONObject row, ResMessageSource source){
        try {
            if(null != row){
                // 设置虚拟化类型
                row.put("virtualType", VirtualConvertCache.getItVirtualType(info.getCloudType()));
                // 构建主对象
                ResMessageManage middleMessage = ResMessageManage.create(row, info.getCloudId());
                middleMessage.setMessageTime(info.getMessageDate());
                middleMessage.setRmPoolId(info.getRmPoolId());
                middleMessage.setSourceId(source.getSourceId());
                middleMessage.setCloudType(info.getCloudType());
                middleMessage.setCloudType(info.getCloudId());
                middleMessage.setStandardCode(info.getStandardCode());
                middleMessage.setMessageSource(info.getSourceTheme());
                // 执行Id处理脚本
                Script script = GroovyScriptCache.getScript(source.getKeyScriptId());
                // 构建入参
                script.invokeMethod(source.getIdScriptCode(), middleMessage);
                if(null != middleMessage.getMessageId()){
                    // 先判断消息标签 add | edit
                    info.getJudgeRowTagFun().accept(info, middleMessage);
                    // 执行特殊主题处理
                    abstractAnalysisHandle.analysisSpecial(middleMessage, info);
                }
                judgeSubSource(info, row, middleMessage.getMessageId());
            }
        } catch (Exception e) {
            log.error("消息解析失败:{}-{}", JSON.toJSONString(info), JSON.toJSONString(row), e);
        } finally {
            info.getDownLatch().countDown();
        }
    }

    /**
     * 判断是否存在子解析源
     *
     * @param info 解析流转对象，主要公用信息的保存
     * @param row  单个解析实体
     * @author xiazunjun
     * @date 2023/8/15 17:16
     */
    private void judgeSubSource(CommonFlowInfo info, JSONObject row, String parentId) {
        if(StrUtil.isNotEmpty(parentId)){
            // 判断是否存在子集
            String sourceTheme = info.getSourceTheme();
            List<String> subThemes = BaseCache.getSubThemes(sourceTheme);
            for (String subTheme : subThemes) {
                // 根据规则获取其字段名
                String fieldName = subTheme.replace(sourceTheme + CommonEnums.JOIN.DEFAULT.getValue(), "");
                String key = AnalysisCommonUtil.commonBuildStr(info.getCacheKeyPrefix(), sourceTheme,info.getThreadName());
                JSONObject jsonObject = SubResourceCache.subAnalysisContains(key, subTheme);
                JSONArray subThemeRows = jsonObject.getJSONArray(subTheme);
                abstractAnalysisHandle.analysisSubResource(sourceTheme, row,parentId, fieldName, subThemeRows);
            }
        }
    }
}
